<?php
class Engine_Core
{
	/**
	 * @var Engine_Core
	 */
	protected static $_instance;

	/**
	 * @var Engine_Adapter
	 */
	protected $_adapter;

	/**
	 * @var Zend_Config
	 */
	protected $_config;

	protected function __construct()
	{
		$coreConfig = array();
		$parentConfig = array();
		$selfConfig = array();
		
		$coreConfigPath = ROOT . '/library/Engine/Core/config.php';

		if (strpos(get_class($this), '_core')) {
			$selfConfigPath   = APPLICATION_PATH . '/modules/' . str_replace('_', '/', get_class($this))        . '/config.php';
			$parentConfigPath = APPLICATION_PATH . '/'         . str_replace('_', '/', get_parent_class($this)) . '/config.php';
		} else {
			$selfConfigPath   = APPLICATION_PATH . '/'         . str_replace('_', '/', get_class($this))        . '/config.php';
			$parentConfigPath = APPLICATION_PATH . '/'         . str_replace('_', '/', get_class($this))        . '/config.php';
		}

		if (file_exists($coreConfigPath)) {
			$coreConfig = require $coreConfigPath;
		}

		if (file_exists($parentConfigPath)) {
			$parentConfig = require $parentConfigPath;
		}

		if (file_exists($selfConfigPath)) {
			$selfConfig = require $selfConfigPath;
		}

		//var_dump($coreConfigPath, $parentConfigPath, $selfConfigPath);

		$config = array_merge($coreConfig, $parentConfig, $selfConfig);

		//var_dump($config);

		$this->_config = new Zend_Config($config, true);
	}

	/**
	 * @return Engine_Adapter
	 */
	protected function getAdapter()
	{
		if (empty($this->_adapter)) {
			if (!$this->_adapter = Engine_Adapter::factory(get_class($this), $this)) {
				if (!$this->_adapter = Engine_Adapter::factory(get_parent_class($this), $this)) {
					$this->_adapter = new Engine_Adapter($this);
				}
			}
		}

		return $this->_adapter;
	}

	/**
	 * @return Zend_Config
	 */
	public function getConfig()
	{
		return $this->_config;
	}

	/**
	 * @param array $params
	 * @return Engine_Core_Wrapper
	 */
	protected function _getEntry($params = array())
	{
		return $this->getAdapter()->getEntry($params);
	}

	/**
	 * @param array $params
	 * @return Engine_Core_Collection
	 */
	protected function _getCollection($params = array())
	{
		return $this->getAdapter()->getCollection($params);
	}

	/**
	 * @param array $params
	 * @return Engine_Core_Collection
	 */
	public function getCollection($params = array())
	{
		return $this->_getCollection($params);
	}

	/**
	 * @param array $params
	 * @return Engine_Core_Wrapper
	 */
	public function getEntry($params = array())
	{
		return $this->_getEntry($params);
	}

	/**
	 * @param  $id
	 * @return Engine_Core_Wrapper
	 */
	public function getNextEntry($id)
	{
		return $this->_getEntry(array(
			'criterion' => 'next',
			'id' => $id
		));
	}

	/**
	 * @param  $id
	 * @return Engine_Core_Wrapper
	 */
	public function getPreviousEntry($id)
	{
		return $this->_getEntry(array(
			'criterion' => 'previous',
			'id' => $id
		));
	}

	/**
	 * @param  $id
	 * @return Engine_Core_Wrapper
	 */
	public function getEntryById($id)
	{
		return $this->_getEntry(array(
			'criterion' => 'byId',
			'id' => $id
		));
	}

	/**
	 * @param  $alias
	 * @return Engine_Core_Wrapper
	 */
	public function getEntryByAlias($alias)
	{
		return $this->_getEntry(array(
			'criterion' => 'byAlias',
			'alias' => $alias
		));
	}

	/**
	 * @param array $params
	 * @return int
	 */
	public function saveEntry($params = array())
	{
		return $this->getAdapter()->saveEntry($params);
	}

	/**
	 * @param array $params
	 * @return void
	 */
	protected function _deleteEntry($params = array())
	{
		$this->getAdapter()->deleteEntry($params);
	}

	/**
	 * @param int $id
	 * @return void
	 */
	public function deleteEntryById($id = null)
	{
		$this->_deleteEntry(array('id' => $id));
	}

	/**
	 * @return Engine_Core_Wrapper
	 */
	public function getRandomEntry()
	{
		return $this->_getEntry(array(
			'criterion' => 'byRandom'
		));
	}

	/**
	 * @return Engine_Core_Wrapper
	 */
	public function getLastEntry()
	{
		return $this->_getEntry(array(
			'criterion' => 'last'
		));
	}

	/**
	 * @return Engine_Core_Wrapper
	 */
	public function getFirstEntry()
	{
		return $this->_getEntry(array(
			'criterion' => 'first'
		));
	}
}